<?php

namespace App\Http\Controllers\Order;

use Auth;
use Log;
use DefaultConfig;
use Illuminate\Validation\Rule;
use Validator;
use App\Model\Orders\Order;
use App\Model\Roles\Permission;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Mockery\Exception;
use Illuminate\Support\Facades\Schema;

class OrderController extends Controller
{
    const SERVICE_CONFIRM_STATUS = 2;//服务商确认标志
    const ORDER_END_STATUS = 1;//服务商填写服务具体信息，订单结束
    const VALIDATOR_SUCCESS = 200;  //验证成功
    const VALIDATOR_ERROR   = 3008;  //验证失败
    const CREATE_ORDER = 'CREATE_ORDER';   //新建订单
    const UPDATE_ORDER = 'UPDATE_ORDER';   //更新订单

    private $orderByDefault = 'created_at';
    private $sortDefault    = 'desc';
    /**
     * 添加订单
     * @param Request $request
     * @return mixed
     */
    public function createOrder(Request $request)
    {
        $result = $this->result();
        $requestArr = $request->all();

        try
        {
            $result = $this->validatorOrderInfo($requestArr);
            if($result['errorCode'] == self::VALIDATOR_ERROR)
            {
                throw new Exception(config('result.errorOrderValidateMsg'), config('result.errorOrderValidateCode'));
            }

            //验证通过，数据格式化
            $params = $this->setOrderInfo($requestArr, self::CREATE_ORDER);

            $order = new Order();
            $order->create($params);
        }
        catch (Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }

        return $result;
    }

    /**
     * 获取订单列表
     * @param Request $request
     * @return mixed
     */
    public function getOrderList(Request $request)
    {
        $result  = $this->result();
        $requestArr = $request->all();

        try
        {
            $validator = Validator::make($requestArr, [
                'service_confirm'  => 'integer',
                'manage_confirm'   => 'integer',
                'start_time'       => 'date',
                'end_time'         => 'after:start_time',
                'order_by'         => [
                    Rule::in(Schema::getColumnListing('orders')),
                ],
                'sort'             => [
                    Rule::in(['desc', 'asc']),
                ],
                'pageSize'        => 'integer',
            ]);

            if($validator->fails())
            {
                $errors = $validator->errors();
                $result['service_confirm'] = $errors->first('service_confirm');
                $result['manage_confirm']  = $errors->first('manage_confirm');
                $result['start_time']      = $errors->first('start_time');
                $result['end_time']        = $errors->first('end_time');
                $result['order_by']        = $errors->first('order_by');
                $result['sort']            = $errors->first('sort');
                $result['pageSize']        = $errors->first('pageSize');
                throw new Exception(config('result.errorOrderFilterMsg'), config('result.errorOrderFilterCode'));
            }
            $orders = new Order();
            $params = array();
            //是否筛选服务商确认状态
            if(isset($requestArr['service_confirm']))
            {
                $params['service_confirm'] = (int)$requestArr['service_confirm'];
            }
            //是否筛选管理员确认状态
            if(isset($requestArr['manage_confirm']))
            {
                $params['manage_confirm'] = (int)$requestArr['manage_confirm'];
            }
            //时间筛选
            if(isset($requestArr['start_time']))
            {
                $params[] = ['start_time', '>=', trim($requestArr['start_time'])];
            }
            if(isset($requestArr['end_time']))
            {
                $params[] = ['end_time', '<=', trim($requestArr['end_time'])];
            }
            //获取当前登录用户的角色
            $permission = $request->session()->get('permission');
            //如果不是管理员，筛选自己的订单
            if($permission == config('app.permissions')[DefaultConfig::USER])
            {
                $params['user_id'] = Auth::id();
            }
            else if ($permission == config('app.permissions')[DefaultConfig::SERVICE])
            {
                $params['service_id'] = Auth::id();
            }
            //默认排序
            $orderBy = $this->orderByDefault;
            $sort    = $this->sortDefault;
            //排序字段
            if (isset($requestArr['order_by']))
            {
                $orderBy = trim($requestArr['order_by']);
            }
            if (isset($requestArr['sort']))
            {
                $sort = trim($requestArr['sort']);
            }
            $pageSize = isset($requestArr['pageSize']) ? (int)$requestArr['pageSize'] : config('app.pageSize');
            $time1 = microtime(true);
            $orders = $orders->leftjoin('users', 'orders.service_id','=', 'users.id')
                ->select('orders.*', 'users.name as service_name')
                ->where($params)
                ->orderBy($orderBy, $sort)
                ->paginate($pageSize)
                ->toArray();
            $time2 = microtime(true);
            $time = round($time2-$time1, 3);
            Log::info('[筛选订单列表]耗时: ' . $time);

            $result['order_info'] = $this->setResultOrderList($orders);
        }
        catch (Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }

        return $result;
    }

    /**
     * 获取某订单详情
     * @param Request $request
     * @param Order $order
     * @return mixed
     */
    public function getOrderInfo(Request $request, Order $order)
    {
        $result = $this->result();
        try
        {
            if((Auth::id()!=$order->user_id) &&
                ($request->session()->get('permission')!=DefaultConfig::ADMIN))
            {
                throw new Exception(config('result.errorSelectOrderMsg'), config('result.errorSelectOrderCode'));
            }
            $order->toArray();
            $order['bus'] = json_decode($order['bus'], true);
            $order['class'] = json_decode($order['class'], true);
            $result['data'] = $order;
        }
        catch (Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }

        return $result;
    }

    /**
     * 更新订单信息
     * @param Request $request
     * @param Order $order
     * @return mixed
     */
    public function updateOrder(Request $request, Order $order)
    {
        $result = $this->result();
        $requestArr = $request->all();

        try
        {
            $uid = Auth::id();
            $orderModel = new Order();
            $order_uid = $order->user_id;
            //用户id和订单中用户id不符
            if($uid !== $order_uid)
            {
                throw new Exception(config('result.errorSelectOrderToUpdateMsg'), config('result.errorSelectOrderToUpdateCode'));
            }
            $result = $this->validatorOrderInfo($requestArr);
            if($result['errorCode'] == self::VALIDATOR_ERROR)
            {
                throw new Exception(config('result.errorOrderValidateMsg'), config('result.errorOrderValidateCode'));
            }
            //验证通过，数据格式化
            $params = $this->setOrderInfo($requestArr, self::UPDATE_ORDER);

            $orderModel->where(['id' => $order->id])->update($params);
        }
        catch (Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }

        return $result;
    }

    /**
     * 服务商确认订单
     * @param Order $order
     * @return mixed
     */
    public function serviceConfirm(Order $order)
    {
        $result = $this->result();
        try
        {
            //该订单已确认过
            if($order->service_confirm == self::SERVICE_CONFIRM_STATUS)
            {
                throw new Exception(config('result.errorServiceConfirmedMsg'), config('result.errorServiceConfirmedCode'));
            }
            //服务商状态置为确认状态
            $updateResult = $order->update(['service_confirm' => self::SERVICE_CONFIRM_STATUS]);
            if(!$updateResult)
            {
                throw new Exception(config('result.errorServiceConfirmMsg'), config('result.errorServiceConfirmCode'));
            }
        }
        catch(Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }
        return $result;
    }

    /**
     * 服务商提交补充信息
     * @param Request $request
     * @param Order $order
     * @return mixed
     */
    public function supplyOrderInfo(Request $request, Order $order)
    {
        $result = $this->result();
        $requestArr = $request->all();

        try
        {
            $serviceId = Auth::id();
            //判断是否是该服务商的订单
            if($order->service_id != $serviceId)
            {
                throw new Exception(config('result.errorServiceSupplyInfoMsg'), config('result.errorServiceSupplyInfoCode'));
            }
            //验证提交信息
            $result = $this->validatorOrderServiceInfo($requestArr);
            if($result['errorCode'] == self::VALIDATOR_ERROR)
            {
                throw new Exception(config('result.errorOrderValidateMsg'), config('result.errorOrderValidateCode'));
            }
            $license = json_decode(trim($requestArr['license']));
             //计算总价，和前端计算不一致时且不是手动填写的，抛出异常
            $total = doubleval($requestArr['total']);
            //不手动填写
            if($requestArr['manual'] == false)
            {
                $total = doubleval($requestArr['unit_price']) * count($license) * doubleval($requestArr['kilometers']);
                $total = round($total, 2);
                if($total != $requestArr['total'])
                {
                    throw new Exception(config('result.errorTotalCalMsg'), config('result.errorTotalCalCode'));
                }
            }

            //入库过滤
            foreach ($license as $key => $value)
            {
                $license[$key] = trim($value);
            }
            $params['unit_price'] = doubleval($requestArr['unit_price']);
            $params['license']    = json_encode($license);
            $params['kilometers'] = doubleval($requestArr['kilometers']);
            $params['total']      = $total;
            $params['service_confirm'] = self::ORDER_END_STATUS;

            $updateResult = $order->where('id', $order->id)->update($params);
            if(!$updateResult)
            {
                throw new Exception(config('result.errorServiceUpdateOrderMsg'), config('result.errorServiceUpdateOrderCode'));
            }
        }
        catch (Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }
        return $result;
    }

    /**
     * 删除订单
     * @param Request $request
     * @param Order $order
     * @return mixed
     */
    public function removeOrder(Request $request, Order $order)
    {
        $result = $this->result();

        try
        {
            //该订单已删除过
            if($order->deleted_at != null)
            {
                throw new Exception(config('result.errorOrderRemoveMsg'), config('result.errorOrderRemoveCode'));
            }
            $permission = $request->session()->get('permission');
            $uid = Auth::id();
            $order_uid = $order->user_id;
            //管理员，直接删
            if($permission==DefaultConfig::ADMIN || $uid==$order_uid)
            {
                $order->delete();
            }
            //用户id和订单中用户id不符，或者不是管理员
            else
            {
                throw new Exception(config('result.errorOrderRemoveMsg'), config('result.errorOrderRemoveCode'));
            }
        }
        catch(Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }
        return $result;
    }


    /**
     * 管理员查看已删除订单
     * @param Request $request
     * @return array|mixed
     */
    public function getRemoveOrderList(Request $request)
    {
        $result = $this->result();
        $requestArr = $request->all();

        try
        {
            //默认排序
            $orderBy = $this->orderByDefault;
            $sort    = $this->sortDefault;
            //排序字段
            if (isset($requestArr['order_by']))
            {
                $orderBy = trim($requestArr['order_by']);
            }
            if (isset($requestArr['sort']))
            {
                $sort = trim($requestArr['sort']);
            }
            $pageSize = isset($requestArr['pageSize']) ? (int)$requestArr['pageSize'] : config('app.pageSize');
            $order = new Order();
            $orders = $order->leftjoin('users', 'orders.service_id','=', 'users.id')
                ->select('orders.*', 'users.name as service_name')
                ->onlyTrashed()
                ->orderBy($orderBy, $sort)
                ->paginate($pageSize)
                ->toArray();

            $result[] = $this->setResultOrderList($orders);

        }
        catch (Exception $exception)
        {
            $result['errorMsg']  = $exception->getMessage();
            $result['errorCode'] = $exception->getCode();
        }

        return $result;
    }

    /**
     * 订单信息验证
     * @param $requestArr
     * @return array
     */
    private function validatorOrderInfo($requestArr)
    {
        $error = 0;
        $result = $this->result();
        $result['errorCode'] = self::VALIDATOR_SUCCESS;
        $validator = Validator::make($requestArr, [
            'people'      =>   'required | min:3',
            'tel'         =>   'required | min:11',
            'purpose'     =>   'required',
            'start_time'  =>   'required | date',
            'end_time'    =>   'required | date | after:start_time',
            'bus'         =>   'required',
            'bus_num'     =>   'required | integer',
            'start_route' =>   'required | string',
            'end_route'   =>   'required | string',
            'service_id'  =>   'required | integer',
            'num_people'  =>   'required | integer',
        ]);

        //选实习的时候必须填写class信息
        $validator->sometimes('class', 'required | string', function($input) {
            return $input->purpose == 1 ? true : false;
        });

        $service_id = isset($requestArr['service_id']) ? (int)$requestArr['service_id'] : 0;
        $permission = new Permission();
        $type = $permission->getUserPermission($service_id);
        if($type != null)
        {
            //所选服务商ID不是服务商的情况
            if($type->permission != 2)
            {
                $result['service_id']  = config('result.errorSelectServiceMsg');
                $error++;
            }
        }
        else
        {
            $error++;
        }

        $purposes = config('app.purposes');
        $purpose = array_key_exists('purpose', $requestArr) ? $requestArr['purpose'] : null;
        if(!array_key_exists($purpose, $purposes))
        {
            $result['purpose'] = config('result.errorSelectPurposeMsg');
            $error++;
        }

        if($validator->fails() || $error)
        {
            $errors = $validator->errors();
            $result['errorCode']   = self::VALIDATOR_ERROR;
            $result['people']      = $errors->first('people');
            $result['tel']         = $errors->first('tel');
            $result['purpose']     = isset($result['purpose']) ? $result['purpose'] : $errors->first('purpose');
            $result['start_time']  = $errors->first('start_time');
            $result['end_time']    = $errors->first('end_time');
            $result['bus']         = $errors->first('bus');
            $result['bus_num']     = $errors->first('bus_num');
            $result['start_route'] = $errors->first('start_route');
            $result['end_route']   = $errors->first('end_route');
            $result['service_id']  = isset($result['service_id']) ? $result['service_id'] : $errors->first('service_id');
            $result['num_people']  = $errors->first('num_people');
            $result['class']       = $errors->first('class');
        }

        return $result;
    }

    /**
     * 订单信息格式化入库
     * @param $type
     * @param $requestArr
     * @return mixed
     */
    private function setOrderInfo($requestArr, $type)
    {
        if ($type == self::CREATE_ORDER)
        {
            $params['user_id'] = Auth::id();
        }
        $params['people']      = trim($requestArr['people']);
        $params['tel']         = trim($requestArr['tel']);
        $params['purpose']     = intval($requestArr['purpose']);
        $params['start_time']  = $requestArr['start_time'];
        $params['end_time']    = $requestArr['end_time'];
        $params['bus']         = json_encode($requestArr['bus']);
        $params['bus_num']     = trim($requestArr['bus_num']);
        $params['start_route'] = trim($requestArr['start_route']);
        $params['end_route']   = trim($requestArr['end_route']);
        $params['service_id']  = (int)$requestArr['service_id'];
        $params['num_people']  = (int)$requestArr['num_people'];
        //选择实习时，需要填写班级信息
        if($params['purpose'] == 1)
        {
            $params['class'] = trim(json_encode($requestArr['class']));
        }

        return $params;
    }


    /**
     * 服务商订单信息校验
     * @param $requestArr
     * @return mixed
     */
    public function validatorOrderServiceInfo($requestArr)
    {
        $result = $this->result();
        $result['errorCode'] = self::VALIDATOR_SUCCESS;
        $validator = Validator::make($requestArr, [
            'unit_price'  =>  'required | numeric | min:0',
            'license'     =>  'required',
            'kilometers'  =>  'required | numeric | min:0',
            'total'       =>  'required | numeric',
            'manual'      =>  'required | boolean'
        ]);

        if($validator->fails())
        {
            $errors = $validator->errors();
            $result['errorCode']   = self::VALIDATOR_ERROR;
            $result['unit_price']  = $errors->first('unit_price');
            $result['license']     = $errors->first('license');
            $result['kilometers']  = $errors->first('kilometers');
            $result['total']       = $errors->first('total');
            $result['manual']      = $errors->first('manual');
        }

        return $result;
    }

    /**
     * 订单列表返回格式化
     * @param $orders
     * @return mixed
     */
    private function setResultOrderList($orders)
    {
        if(empty($orders))
        {
            return [];
        }
        foreach ($orders['data'] as &$order)
        {
            $order['bus']   = json_decode($order['bus']);
            $order['class'] = json_decode($order['class']);
        }
        unset($order);
        //获取的数据
        $result['data']          = $orders['data'];
        //总条数
        $result['total']         = $orders['total'];
        //当前页码
        $result['current_page']  = $orders['current_page'];
        //最后一页页码
        $result['last_page']     = $orders['last_page'];
        //下一页url
        $result['next_page_url'] = $orders['next_page_url'];
        //上一页url
        $result['prev_page_url'] = $orders['prev_page_url'];

        return $result;
    }

    public function test()
    {
        $user = Auth::user();
        echo json_encode(Auth::user()->permissions);
    }

}
